package com.riteny.paymentgateway.swifypass.service;

import com.riteny.paymentgateway.swifypass.exception.SwiftPassPaymentGatewayException;
import com.riteny.paymentgateway.swifypass.common.SwiftPassPaymentGatewayUtil;
import com.riteny.paymentgateway.swifypass.entity.SwiftPassOrderQueryParams;
import com.riteny.paymentgateway.swifypass.entity.SwiftPassOrderSubmitParams;
import com.riteny.paymentgateway.swifypass.entity.SwiftPassQueryPaymentOrderResponseEntity;
import com.riteny.paymentgateway.swifypass.entity.SwiftPassSubmitPaymentOrderResponseEntity;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.util.UUID;

/**
 * @author Riteny
 * 2022/1/5  15:56
 */
abstract class AbstractSwiftPassPaymentGatewayService {

    /**
     * 調用統一下單接口
     *
     * @param params 支付網關參數，訂單參數等
     * @return 訂單創建結果
     */
    public SwiftPassSubmitPaymentOrderResponseEntity submitUnityOrder(SwiftPassOrderSubmitParams params) {

        /*
         * 請求威富通-中銀統一下單接口
         * 請求前，會對入參（requestXml）内的所有字段進行簽名（SHA256），簽名後會將簽名值添加請求XML節點内
         * 同時，請求結束時，對方會對返回值進行簽名（SHA256），這次需要使用對方的簽名值進行驗簽，以保證内容的有效性
         * 儅方法結束時，獲取的responseXml為已經驗簽通過的有效返回值
         */
        Element requestXml = getUnityOrderSubmitRequestXml(params);
        Element responseXml = SwiftPassPaymentGatewayUtil.requestPaymentGatewayTemplate(params.getPaymentGatewayKey()
                , params.getPaymentGatewayUrl(), requestXml);

        String status = responseXml.elementText("status");
        String errorCode = responseXml.elementText("err_code");
        String errorMsg = responseXml.elementText("err_msg");

        /*
         * 解析返回參數
         * 返回中銀格式的參數或者抛出訂單創建異常
         */
        if (!SwiftPassPaymentGatewayUtil.SWIFT_PASS_RESPONSE_SUCCESS.equals(status)) {
            throw new SwiftPassPaymentGatewayException(errorCode, errorMsg);
        } else {
            return new SwiftPassSubmitPaymentOrderResponseEntity(responseXml);
        }
    }

    /**
     * 獲取統一下單接口的調用參數，XML 格式
     *
     * @param params 支付網關參數，訂單號
     * @return XML 格式请求参数
     */
    abstract Element getUnityOrderSubmitRequestXml(SwiftPassOrderSubmitParams params);


    /**
     * 使用訂單號調用支付網關獲取訂單詳情
     *
     * @param params 支付網關參數，訂單號
     * @return 訂單詳情
     */
    public SwiftPassQueryPaymentOrderResponseEntity queryUnityOrder(SwiftPassOrderQueryParams params) {

        Element requestXml = getUnityOrderQueryRequestXml(params.getPaymentGatewayMchId(), params.getOrderNo());

        Element responseXml = SwiftPassPaymentGatewayUtil.requestPaymentGatewayTemplate(params.getPaymentGatewayKey(), params.getPaymentGatewayUrl(), requestXml);

        return new SwiftPassQueryPaymentOrderResponseEntity(responseXml);
    }

    /**
     * 獲取統一訂單查詢接口的調用參數，XML 格式
     *
     * @param paymentGatewayMchId 支付網關商戶號
     * @param orderUuid           訂單號
     * @return XML 格式请求参数
     */
    protected Element getUnityOrderQueryRequestXml(String paymentGatewayMchId, String orderUuid) {

        Document doc;

        try {
            doc = DocumentHelper.parseText("<xml>\n" +
                    "    <service>unified.trade.query</service>\n" +
                    "    <version>2.0</version>\n" +
                    "    <charset>UTF-8</charset>\n" +
                    "    <sign_type>SHA256</sign_type>\n" +
                    "    <mch_id>" + paymentGatewayMchId + "</mch_id>\n" +
                    "    <out_trade_no>" + orderUuid + "</out_trade_no>\n" +
                    "    <nonce_str>" + UUID.randomUUID().toString().replace("-", "") + "</nonce_str>\n" +
                    "</xml>");
        } catch (DocumentException e) {
            throw new SwiftPassPaymentGatewayException(SwiftPassPaymentGatewayException.UNKNOWN_ERROR, e.getMessage());
        }

        return doc.getRootElement();
    }
}
